#! /usr/bin/env python

__author__="Hong Phuc Bui, Sarah Theobald "
__date__ ="$Dec 2, 2011 10:54:44 AM$"


import pexpect;
import signal
import os

gpInitScript   =  os.path.dirname(__file__) + r"/gpinitcode.gp"
'''Pfad zur Init-Skript der GP'''

class GPConnector():#
	'''
		stellt eine Schnittstelle zur GP-Session zur Verfuegung.
	'''
	gpPrompt	   = r"\?"
	gpAnswerToken  = r"%[0-9]+ ="
	gpError        = r"\*\*\*"
	gpGoodbyte     = r"Goodbye!"
	# Yes, I known, goodbye and not good byte, but sometime you may get some bad bytes
	
	
	def __init__(self,gpExecute="gp", \
				 timeout=30, \
				 initScript= gpInitScript):#
		'''
			:param gpExecute: der Befehl zum Starten des GP
			:param timeout: Zeit in Sekunden, um ein GP-Commando auszufuehren
			:param initScript: Die Init-Skript von GP, referenziert auf
				:py:data:`~pythoncrypt.gp.GPConnector.gpInitScript`
		'''

		self.gpExecute=gpExecute
		self.timeout = timeout
		self.p = pexpect.spawn(self.gpExecute, timeout=self.timeout)
		self.initScript = initScript
		
		i = self.p.expect([GPConnector.gpPrompt , pexpect.TIMEOUT])
		if i == 0: # OK, 
			self.p.expect(GPConnector.gpPrompt)
			j = self.p.expect([
				GPConnector.gpPrompt,  # good, GP is ready to get work, you can sent it some commands 
				pexpect.TIMEOUT,       # something went wrong, please check if GP is correctly installed on your system
				GPConnector.gpGoodbyte # pleas check how you start GP, don't start with a pipe (<)
			])
			if j == 0:
				cmdRemoveColor = "default(colors, no);"
				self.p.sendline(cmdRemoveColor)
				self.p.expect(GPConnector.gpPrompt)
				
				readInit = 'read("%s")'%self.initScript
				self.p.sendline(readInit)
				k = self.p.expect( [
					GPConnector.gpPrompt,# init script should not write anything to console
					GPConnector.gpAnswerToken,# but is OK, if it writes s.t.
					GPConnector.gpError,# well, init script has error
					pexpect.TIMEOUT, # init script must not do something to long
					])
				# bis hier: bereit fuer arbeiten
				if k == 0: self.startedOK = True;
				if k == 1: self.startedOK = True;
				if k == 2: 
					self.startedOK = False;
					raise Exception("GP gets error while reading file >>%s<<"%self.initScript)
				if k == 3:
					self.startedOK = False;
					raise Exception("GP took too much time to execute file >>%s<<"%self.initScript)
			elif j == 1:
				self.startedOK = False
				raise Exception(
					"GP took too long to get start. Please check if GP is correctly installed!")
			elif j == 2:
				self.startedOK = False
				raise Exception(
					"GP closes automatically. Please check how you start GP")

	def turnOffGP(self):#
		"""
		schliest die Kopplung zwichen Python und GP
		"""
		if self.p.isalive():
			self.p.sendline("quit()");
			r = self.p.expect([r"Goodbye!",pexpect.TIMEOUT]);
			if r == 1:
				self.p.kill(signal.SIGKILL)
		
		
	def sendGP(self,gpCmd):
		'''
		send gpCmd and returns the raw result from gp
		'''
		if self.p.isalive():
			self.p.sendline(gpCmd)
			i = self.p.expect([
							pexpect.TIMEOUT, 
							GPConnector.gpAnswerToken,
							GPConnector.gpPrompt,
							GPConnector.gpError])

			if i == 0:#TODO: dont send -9
				self.p.kill(signal.SIGINT)
				print "TIME OUT"
				print gpCmd.strip()
				return None
			if i == 1:
				self.p.expect(GPConnector.gpPrompt)
				return self.p.before.strip()
			if i == 2:
				return None
			if i == 3:
				print "GP ERROR"
				print gpCmd
				return None
			
def call_gp_script(script_name,timeout=30):
	cmd = "gp " + script_name
	c = GPConnector(cmd,timeout)


if __name__ == "__main__":
	f = file("prime.py","w")
	f.write("#! /usr/bin/env/ python \n")
	f.close()
	# c = Connector(gpExecute="gp gpinit.gp", timeout=40)		 
	
'''

	x = c.sendGP("a=5");
	print x
	
	
	x = c.sendGP(";");
	print x
	
	x = c.sendGP("1+2");
	print x
	
	c.turnOffGP()
	x = c.sendGP("factor(2^12-1);x");
	print x
'''	
			
			
			
			
			
			
			
			
			


